﻿using System;
using System.Collections.Generic;
using Property;
using Property.DelegateBased;
using Property.Samples.Concepts;

namespace Property.Samples
{
    //Pair of interfaces containing properties.
    public interface IValue<TType>
    {
        TType Value
        {
            get;
            set;
        }
    }
    public interface INamedValue<TType> : IValue<TType>
    {
        String Name
        {
            get;
            set;
        }
    }

    public interface ISample : INamedValue<int>
    {

    }

    

    

    public class Program
    {
        
        static void Main(string[] args)
        {

            //Autoimplementing interface using Dictionary container.
            var instance = DictionaryBased.Implementation.Of<ISample>.Create<Func<ISample>>.New();

            var otherInstance = DictionaryBased.Implementation.Of<ISample>.Create<Func<String, ISample>>.New("Sample .ctor parameter.");

            instance.Name = otherInstance.Name;
            instance.Value = 255;
            instance.Value ^= 12;

            var dictionary = (DictionaryBased)instance;

            dictionary.WriteData();

            //Autoimplementing change tracking adapter for interface.
            var proxy = InterfaceProxy<ISample>.Wrap(instance);

            Console.WriteLine();

            proxy.Value += 12;
            proxy.Name = "Hello world!";

            Console.WriteLine();

            dictionary.WriteData();

            Console.WriteLine();

            //Autoimplementing INotifyPropertyChanged in derived type.
            var cityConcept = CityConcept.New();

            cityConcept.PropertyChanged+=((s,a)=>Console.WriteLine("{0} property changed.",a.PropertyName));

            var id = cityConcept.Identity;
            cityConcept.Identity = Guid.NewGuid();
            var i2 = cityConcept as IObjectWithIdentity;
            var id2 = i2.Identity;
            i2.Identity = Guid.NewGuid();

            cityConcept.Coordinates = new Point() { Latitude = 10, Longitude = cityConcept.Coordinates.Longitude };
            var i1 = cityConcept as IObjectWithCoordinates;
            i1.Coordinates = new Point() { Latitude = i1.Coordinates.Latitude, Longitude = 20 };

            cityConcept.Modified = !cityConcept.Modified;

            var concept = cityConcept as Concept;

            concept.Modified = !concept.Modified;

            Console.ReadLine();
            return;
        }
    }
}
